package tetris;
// <editor-fold defaultstate="collapsed" desc="import">
import main.Main;
import main.Frame;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Hashtable;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import tetris.Shape.Tetrominoes;
// </editor-fold>
public class Board extends JPanel implements ActionListener {
    // <editor-fold defaultstate="collapsed" desc="Variable Declaration">

    public javax.swing.JPanel buttonPanel;
    public javax.swing.JTextArea listUserField;
    public javax.swing.JButton exitButton;
    public javax.swing.JPanel controlPanel;
    public javax.swing.JTextArea highScoreField;
    public javax.swing.JScrollPane highScoreScroll;
    public javax.swing.JLabel nextLabel;
    public javax.swing.JPanel nextPanel;
    public javax.swing.JButton pauseButton;
    public javax.swing.JLabel scoreField;
    public javax.swing.JLabel scoreLabel;
    public javax.swing.JButton startButton;
    public javax.swing.JLabel statusField;
    public javax.swing.JButton loginButton;
    private static final long serialVersionUID = 1L;
    final int BoardWidth = 15;
    final int BoardHeight = 29;
    final int BoardX = 345;
    final int BoardY = 638;
    Timer timer;
    boolean isFallingFinished = false;
    boolean isStarted = false;
    boolean isPaused = false;
    int numLinesRemoved = 0;
    int curX = 0;
    int curY = 0;
    int curX2 = 0, curY2 = 0;
    //JLabel statusbar;
    public Shape curPiece, nextPiece;
    public Shape curPiece2;
    Shape.Tetrominoes[] board, board2;
    public Tetris tetris;
    int shapeOrder = 0;
    public String chuoiBoard1 = "";
    public String chuoiBoard2 = "";

// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Board(Tetris tetris)">
    public Board(Tetris tetris) {
        // <editor-fold defaultstate="collapsed" desc="initBoardPanel">
        setFocusable(true);
        controlPanel = new javax.swing.JPanel();
        nextLabel = new javax.swing.JLabel();
        scoreLabel = new javax.swing.JLabel();
        scoreField = new javax.swing.JLabel();
        statusField = new javax.swing.JLabel();
        nextPanel = new javax.swing.JPanel();
        listUserField = new javax.swing.JTextArea();
        highScoreField = new javax.swing.JTextArea();
        buttonPanel = new javax.swing.JPanel();
        startButton = new javax.swing.JButton();
        pauseButton = new javax.swing.JButton();
        exitButton = new javax.swing.JButton();
        loginButton = new javax.swing.JButton();
        highScoreScroll = new javax.swing.JScrollPane();

        setBackground(new java.awt.Color(0, 0, 0));
        setForeground(new java.awt.Color(255, 255, 255));
        setLayout(null);

        controlPanel.setBackground(new java.awt.Color(0, 0, 0));
        controlPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Control", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, java.awt.Color.white));
        controlPanel.setForeground(new java.awt.Color(255, 255, 255));
        controlPanel.setPreferredSize(new java.awt.Dimension(200, 603));
        controlPanel.setLayout(null);

        nextLabel.setBackground(new java.awt.Color(0, 0, 0));
        nextLabel.setForeground(new java.awt.Color(255, 255, 255));
        nextLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        nextLabel.setText("Next");
        controlPanel.add(nextLabel);
        nextLabel.setBounds(70, 160, 110, 24);

        scoreLabel.setBackground(new java.awt.Color(0, 0, 0));
        scoreLabel.setForeground(new java.awt.Color(255, 255, 255));
        scoreLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        scoreLabel.setText("Score");
        controlPanel.add(scoreLabel);
        scoreLabel.setBounds(68, 280, 110, 22);

        JPanel scorePanel = new JPanel();
        scorePanel.setBounds(50, 310, 140, 30);
        scorePanel.setBackground(Color.YELLOW);
        scorePanel.add(scoreField);
        controlPanel.add(scorePanel);
        scoreField.setForeground(new java.awt.Color(0, 0, 0));
        scoreField.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        scoreField.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        scoreField.setText("00");
        scoreField.setBounds(0, 0, 140, 22);

        statusField.setBackground(new java.awt.Color(255, 255, 255));
        statusField.setForeground(new java.awt.Color(255, 255, 255));
        statusField.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        statusField.setText("Click Start to play game");
        controlPanel.add(statusField);
        statusField.setBounds(18, 590, 205, 23);

        nextPanel.setBackground(new java.awt.Color(0, 0, 0));
        nextPanel.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(255, 255, 255), 1, true));
        nextPanel.setForeground(new java.awt.Color(255, 255, 255));
        nextPanel.setLayout(null);
        controlPanel.add(nextPanel);
        nextPanel.setBounds(50, 189, 140, 80);

        listUserField.setBackground(Color.white);
        listUserField.setFont(new java.awt.Font("Tahoma", 1, 14));
        listUserField.setColumns(20);
        listUserField.setForeground(new Color(204, 102, 0));
        listUserField.setRows(5);
        listUserField.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "DanhSachNguoiChoi", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 13), Color.blue));
        listUserField.setSelectedTextColor(new java.awt.Color(0, 0, 0));
        controlPanel.add(listUserField);
        listUserField.setBounds(18, 350, 205, 82);

        highScoreField.setBackground(new java.awt.Color(255, 255, 255));
        highScoreField.setColumns(20);
        highScoreField.setForeground(new java.awt.Color(0, 0, 0));
        highScoreField.setRows(5);
        highScoreScroll.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "High Score", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 1, 13), java.awt.Color.blue));
        controlPanel.add(highScoreScroll);
        highScoreScroll.setViewportView(highScoreField);
        highScoreScroll.setBounds(18, 440, 205, 116);

        buttonPanel.setBackground(new java.awt.Color(0, 0, 0));
        buttonPanel.setForeground(new java.awt.Color(255, 255, 255));
        buttonPanel.setPreferredSize(new java.awt.Dimension(180, 132));
        buttonPanel.setLayout(null);

        startButton.setText("Start");
        startButton.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        startButton.setMargin(new java.awt.Insets(3, 14, 3, 14));
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(startButton);
        startButton.setBounds(50, 10, 110, 23);

        pauseButton.setText("Pause");
        pauseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pauseButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(pauseButton);
        pauseButton.setBounds(50, 40, 110, 23);

        exitButton.setText("Exit");
        exitButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(exitButton);
        exitButton.setBounds(50, 70, 110, 23);

        loginButton.setText("Login");
        loginButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loginButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(loginButton);
        loginButton.setBounds(50, 100, 110, 23);

        controlPanel.add(buttonPanel);
        buttonPanel.setBounds(18, 16, 210, 132);

        add(controlPanel);
        controlPanel.setBounds(355, 5, 240, 640);
        // </editor-fold>
        this.tetris = tetris;
        curPiece = new Shape();
        nextPiece = new Shape();
        curPiece2 = new Shape();
        NextPiece();
        timer = new Timer(400, this);
        board = new Shape.Tetrominoes[BoardWidth * BoardHeight];
        board2 = new Shape.Tetrominoes[BoardWidth * BoardHeight];
        addKeyListener(new Board.TAdapter());
        clearBoard();

    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Board Dimension">

    int squareWidth() {
        return BoardX / BoardWidth;
    }

    int squareHeight() {
        return BoardY / BoardHeight;
    }

    Shape.Tetrominoes shapeAt(int x, int y) {
        return board[(y * BoardWidth) + x];
    }

    Shape.Tetrominoes shapeAt2(int x, int y) {
        return board2[(y * BoardWidth) + x];
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="MaHoaBoard()">

    public void MaHoaBoard() {
        int boardMH[] = new int[BoardWidth * BoardHeight];
        for (int i = 0; i < BoardWidth * BoardHeight; i++) {
            boardMH[i] = MaHoa(board[i], boardMH[i]);
            chuoiBoard1 += boardMH[i];
        }
    }

    public int MaHoa(Shape.Tetrominoes shape, int boardMH) {

        switch (shape) {
            case NoShape:
                boardMH = 0;
                break;
            case ZShape:
                boardMH = 1;
                break;
            case SShape:
                boardMH = 2;
                break;
            case LineShape:
                boardMH = 3;
                break;
            case TShape:
                boardMH = 4;
                break;
            case SquareShape:
                boardMH = 5;
                break;
            case LShape:
                boardMH = 6;
                break;
            case MirroredLShape:
                boardMH = 7;
                break;
            case BongMaShape:
                boardMH = 8;
                break;
        }
        return boardMH;
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="GiaiMaChuoiBoard(String str)">
    //ket thuc ham nay ta co: board2[shape]

    public void GiaiMaChuoiBoard(String str) {
        System.out.println("Giai ma chuoi board: " + str);
        char[] s = str.toCharArray();//s la bang board[string]
        //xay dung lai bang board [shape]
        for (int i = 0; i < s.length; i++) {
            int x = s[i] - 48;
            board2[i] = GiaiMa(board2[i], x);
        }
    }

    public Shape.Tetrominoes GiaiMa(Shape.Tetrominoes shape, int x) {
        switch (x) {
            case 0:
                shape = Tetrominoes.NoShape;
                break;
            case 1:
                shape = Tetrominoes.ZShape;
                break;
            case 2:
                shape = Tetrominoes.SShape;
                break;
            case 3:
                shape = Tetrominoes.LineShape;
                break;
            case 4:
                shape = Tetrominoes.TShape;
                break;
            case 5:
                shape = Tetrominoes.SquareShape;
                break;
            case 6:
                shape = Tetrominoes.LShape;
                break;
            case 7:
                shape = Tetrominoes.MirroredLShape;
                break;
            case 8:
                shape = Tetrominoes.BongMaShape;
                break;
        }
        return shape;
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Start()">

    public void start() {
        setFocusable(true);
        this.grabFocus();
        if (isStarted) {
            if (isPaused) {
                pause();
            }
            int n = JOptionPane.showConfirmDialog(null, "Do you want restart game", "warning", JOptionPane.YES_NO_OPTION);

            if (n == 0) {
                isStarted = true;
                isFallingFinished = false;
                addscore(0);
                clearBoard();

                newPiece();
                pause();
                timer.start();
                statusField.setText("Playing");
            } else {
                pause();
            }
            //getscorefromserver();
        } else {
            isStarted = true;
            isFallingFinished = false;
            addscore(0);
            clearBoard();
            newPiece();


            timer.start();
            statusField.setText("Playing");
        }
        //getscorefromserver();
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="pause()">

    public void pause() {
        if (!isStarted) {
            return;
        }

        isPaused = !isPaused;
        if (isPaused) {
            timer.stop();
            statusField.setText("Paused");
        } else {
            timer.start();
            statusField.setText("Playing");

        }
        repaint();
        this.grabFocus();
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="NextPiece()">

    private void NextPiece() {
        nextPiece.setRandomShape();
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="newPiece()">

    private void newPiece() {
        //System.out.println(chuoiBoard1);
        //MaHoaBoard();
        //curPiece = nextPiece;
        for (int i = 0; i < nextPiece.coords.length; i++) {
            System.arraycopy(nextPiece.coords[i], 0, curPiece.coords[i], 0, nextPiece.coords[i].length);
        }
        curPiece.pieceShape = nextPiece.pieceShape;
        curPiece.shapeOrder = nextPiece.shapeOrder;
        NextPiece();
        curX = BoardWidth / 2 + 1;
        curY = BoardHeight - 1 + curPiece.minY();

        if (!tryMove(curPiece, curX, curY)) {
            curPiece.setShape(Shape.Tetrominoes.NoShape);
            timer.stop();
            isStarted = false;
            statusField.setText("Game Over");
            tetris.player1.setText("GAME OVER");
            String str = tetris.getTitle();
            if (str.equals("Tetris-Multi")) {
                tetris.gameover();
            } else {
                if (str.equals("Tetris-Single")) {
                    //game over, gui diem len server
                    int i = Integer.parseInt(scoreField.getText());
                    tetris.ghidiemlenserver(i);
                    statusField.setText("Game Over");
                    //JOptionPane.showMessageDialog(null, "game over");
                    //tetris.ghidiemlenserver(Integer.parseInt(scoreField.getText()));
                }
            }
        }
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="readMSG(String input) ">

    public void readMSG(String input) {
        char head = input.charAt(0);
        switch (head) {
            case '1':
                //tetris.startgame();
                break;

        }
    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="paint(Graphics g)">
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        // <editor-fold defaultstate="collapsed" desc="Truyền data Mã Hóa">
        Tetrominoes[] values = Tetrominoes.values();
        curPiece2.setShape(values[shapeOrder]);
        if (tetris.getTitle().equals("Tetris-Multi") && isStarted) {
            tetris.main.sendPosition(curX + "|" + curY + "|" + curPiece.shapeOrder); //    7|d|200|150

        }
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve sọc caro 1">
        for (int i = 0; i < BoardWidth; i++) {
            for (int e = 0; e < BoardHeight; e++) {
                g.setColor(new Color(20, 20, 20));
                g.drawRect(5 + i * squareWidth(), 5 + e * squareHeight(), squareWidth(), squareHeight());
            }
        }// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve sọc caro 2">
        
        for (int i = 0; i < BoardWidth; i++) {
            for (int e = 0; e < BoardHeight; e++) {
                g.setColor(new Color(20, 20, 20));
                g.drawRect(600 + i * squareWidth(), 5 + e * squareHeight(), squareWidth(), squareHeight());
            }
        }// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Bảng Viền Board 1">
        g.setColor(Color.WHITE);
        g.drawRect(5, 5, BoardX, BoardY);// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Bảng Viền Board 2">
        g.drawRect(600, 5, BoardX, BoardY);// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Bảng Trạng thái Board 1">
        for (int i = 0; i < BoardHeight; ++i) {
            for (int j = 0; j < BoardWidth; ++j) {
                Shape.Tetrominoes shape = shapeAt(j, BoardHeight - i - 1);
                if (shape != Shape.Tetrominoes.NoShape) {
                    drawSquare(g, 5 + j * squareWidth(),
                            5 + i * squareHeight(), shape);
                }
            }
        }// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Bảng Trạng thái Board 2">

        for (int i = 0; i < BoardHeight; ++i) {
            for (int j = 0; j < BoardWidth; ++j) {
                Shape.Tetrominoes shape = shapeAt2(j, BoardHeight - i - 1);
                if (shape != Shape.Tetrominoes.NoShape) {
                    drawSquare(g, 600 + j * squareWidth(),
                            5 + i * squareHeight(), shape);
                }
            }
        }// </editor-fold>

        // <editor-fold defaultstate="collapsed" desc="ve Bóng Ma 1">
        if (curPiece.getShape() != Shape.Tetrominoes.NoShape) {
            int newY = curY;
            while (newY > 0) {
                if (!tryMove1(curPiece, curX, newY - 1)) {
                    break;
                }
                --newY;
            }
            for (int i = 0; i < 4; ++i) {
                int x = curX + curPiece.x(i);
                int y = newY - curPiece.y(i);
                
                g.setColor(Color.ORANGE);
                g.drawRect(5 + x * squareWidth(), 5 + (BoardHeight - y - 1) * squareHeight(), squareWidth() - 2, squareHeight() - 2);
            }
        }// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Bóng Ma 2">
        /*
         if (curPiece.getShape() != Shape.Tetrominoes.NoShape) {
         int newY = curY;
         while (newY > 0) {
         if (!tryMove1(curPiece, curX, newY - 1)) {
         break;
         }
         --newY;
         }
         for (int i = 0; i < 4; ++i) {
         int x = curX + curPiece.x(i);
         int y = newY - curPiece.y(i);
         g.setColor(Color.ORANGE);
         g.drawRect(5 + x * squareWidth(), 5 + (BoardHeight - y - 1) * squareHeight(), squareWidth() - 2, squareHeight() - 2);
         }
         }*/
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve CurPiece1">
        if (curPiece.getShape() != Shape.Tetrominoes.NoShape) {
            for (int i = 0; i < 4; i++) {
                int x = curX + curPiece.coords[i][0];
                int y = curY - curPiece.coords[i][1];
                drawSquare(g, 5 + x * squareWidth(), 5 + (BoardHeight - y - 1) * squareHeight(), curPiece.getShape());
            }
        }// </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve CurPiece2">

        if (tetris.getTitle().equals("Tetris-Multi") && isStarted) {
            for (int i = 0; i < 4; i++) {
                int x = curX2 + curPiece2.coords[i][0];
                int y = curY2 - curPiece2.coords[i][1];
                drawSquare(g, 5 + 595 + x * squareWidth(), 5 + (BoardHeight - y - 1) * squareHeight(), curPiece2.pieceShape);
            }
        }
        // </editor-fold>
        // <editor-fold defaultstate="collapsed" desc="ve Next">
        if (nextPiece.getShape() != Shape.Tetrominoes.NoShape) {
            for (int i = 0; i < 4; i++) {
                drawSquare1(g, 475 + nextPiece.coords[i][0] * squareWidth() / 2, 220 + nextPiece.coords[i][1] * squareHeight() / 2, nextPiece.getShape());

            }
        }// </editor-fold>

    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="drawSquare()">
    private void drawSquare(Graphics g, int x, int y, Shape.Tetrominoes shape) {
        Color colors[] = {new Color(0, 255, 255), new Color(255, 0, 0),
            new Color(0, 153, 0), new Color(0, 51, 102),
            new Color(255, 255, 0), new Color(204, 102, 204),
            new Color(255, 153, 0), new Color(160, 0, 160), new Color(70, 70, 70)
        };


        Color color = colors[shape.ordinal()];

        g.setColor(color);
        g.fillRect(x + 2, y + 2, squareWidth() - 4, squareHeight() - 4);

        g.setColor(color.brighter());
        g.drawLine(x, y + squareHeight() - 2, x, y);
        g.drawLine(x, y, x + squareWidth() - 2, y);

        g.setColor(color.darker());
        g.drawLine(x + 2, y + squareHeight() - 2,
                x + squareWidth() - 2, y + squareHeight() - 2);
        g.drawLine(x + squareWidth() - 2, y + squareHeight() - 2,
                x + squareWidth() - 2, y + 2);

    }

    private void drawSquare1(Graphics g, int x, int y, Shape.Tetrominoes shape) {
        Color colors[] = {new Color(0, 255, 255), new Color(200, 0, 0),
            new Color(0, 153, 0), new Color(0, 51, 102),
            new Color(180, 180, 0), new Color(204, 102, 204),
            new Color(255, 153, 0), new Color(102, 0, 102), new Color(70, 70, 70)
        };


        Color color = colors[shape.ordinal()];

        g.setColor(color);
        g.fillRect(x + 2, y + 2, squareWidth() / 2 - 4, squareHeight() / 2 - 4);

        g.setColor(color.brighter());
        g.drawLine(x, y + squareHeight() / 2 - 2, x, y);
        g.drawLine(x, y, x + squareWidth() / 2 - 2, y);

        g.setColor(color.darker());
        g.drawLine(x + 2, y + squareHeight() / 2 - 2,
                x + squareWidth() / 2 - 2, y + squareHeight() / 2 - 2);
        g.drawLine(x + squareWidth() / 2 - 2, y + squareHeight() / 2 - 2,
                x + squareWidth() / 2 - 2, y + 2);

    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="dropDown()">

    private void dropDown() {
        int newY = curY;
        while (newY > 0) {
            if (!tryMove(curPiece, curX, newY - 1)) {
                break;
            }
            --newY;
        }
        pieceDropped();
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="oneLineDown()">

    private void oneLineDown() {
        if (!tryMove(curPiece, curX, curY - 1)) {
            pieceDropped();
        }
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="clearBoard()">

    private void clearBoard() {
        for (int i = 0; i < BoardHeight * BoardWidth; ++i) {
            board[i] = Shape.Tetrominoes.NoShape;
            board2[i] = Shape.Tetrominoes.NoShape;
        }
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="pieceDropped()">

    private void pieceDropped() {
        for (int i = 0; i < 4; ++i) {
            int x = curX + curPiece.x(i);
            int y = curY - curPiece.y(i);
            board[(y * BoardWidth) + x] = curPiece.getShape();
        }
        MaHoaBoard();
        tetris.main.sendChuoiBoard(chuoiBoard1);
        chuoiBoard1 = "";

        removeFullLines();

        if (!isFallingFinished) {

            newPiece();
            //System.out.println(curPiece.shapeOrder);
        }
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="tryMove()">

    private boolean tryMove1(Shape newPiece, int newX, int newY) {
        for (int i = 0; i < 4; ++i) {
            int x = newX + newPiece.x(i);
            int y = newY - newPiece.y(i);
            if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight) {
                return false;
            }
            if (shapeAt(x, y) != Shape.Tetrominoes.NoShape) {
                return false;
            }
        }

        return true;
    }

    private boolean tryMove(Shape newPiece, int newX, int newY) {
        for (int i = 0; i < 4; ++i) {
            int x = newX + newPiece.x(i);
            int y = newY - newPiece.y(i);
            if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight) {
                return false;
            }
            if (shapeAt(x, y) != Shape.Tetrominoes.NoShape) {
                return false;
            }
        }

        curPiece = newPiece;
        curX = newX;
        curY = newY;
        repaint();
        return true;
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="removeFullLines()">

    private void removeFullLines() {
        int numFullLines = 0;
        for (int i = BoardHeight - 1; i >= 0; --i) {
            boolean lineIsFull = true;

            for (int j = 0; j < BoardWidth; ++j) {
                if (shapeAt(j, i) == Shape.Tetrominoes.NoShape) {
                    lineIsFull = false;
                    break;
                }
            }

            if (lineIsFull) {
                ++numFullLines;
                for (int k = i; k < BoardHeight - 1; ++k) {
                    for (int j = 0; j < BoardWidth; ++j) {
                        board[(k * BoardWidth) + j] = shapeAt(j, k + 1);
                    }
                }
            }
        }

        if (numFullLines > 0) {
            numLinesRemoved += numFullLines;
            String str = tetris.getTitle();
            if (str.equals("Tetris-Multi")) {
                tetris.ghidiem(numFullLines);
            }
            addscore(addscore1(numFullLines));
            isFallingFinished = true;
            curPiece.setShape(Shape.Tetrominoes.NoShape);
            repaint();
            int i = Integer.parseInt(scoreField.getText());
        }
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="addALine()">

    public void addALine() {
        for (int i = BoardHeight - 1; i > 0; i--) {
            for (int j = 0; j < BoardWidth; j++) {
                board[(i * BoardWidth) + j] = board[(i - 1) * BoardWidth + j];
            }
        }
        Random ran = new Random();
        int i = ran.nextInt(BoardWidth);
        for (int j = 0; j < BoardWidth; j++) {
            if (j != i) {
                //board[j] = Shape.Tetrominoes.TShape;
                board[j] = Shape.Tetrominoes.BongMaShape;
            } else {
                board[j] = Shape.Tetrominoes.NoShape;
            }
        }
        this.grabFocus();
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="addscore()">

    public void addscore(int newscore) {
        if (newscore > 0) {
            int curscore = Integer.parseInt(scoreField.getText());
            scoreField.setText(Integer.toString(newscore + curscore));
        } else {
            scoreField.setText("00");
        }
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="addscore1()">

    public int addscore1(int diem) {
        switch (diem) {
            case 1:
                diem = 100;
                break;
            case 2:
                diem = 300;
                break;
            case 3:
                diem = 600;
                break;
            case 4:
                diem = 1000;
                break;
        }
        return diem;
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="actionPerformed()">

    public void actionPerformed(ActionEvent e) {
        if (isFallingFinished) {
            isFallingFinished = false;

            newPiece();
        } else {
            oneLineDown();
        }
    }// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="startButtonActionPerformed()">
    private void startButtonActionPerformed(ActionEvent evt) {
        String str = startButton.getText();
        if (statusField.equals("please wait for game")) {
        } else if (str.equals("Start")) {
            start();
            //tetris.main.sendstartgame();
        } else if (str.equals("start room")) {
            startButton.setVisible(false);
            tetris.main.sendstartgame();
        } else {
            return;
        }
        //else {parent.sendstartgame();}
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="pauseButtonActionPerformed()">

    private void pauseButtonActionPerformed(ActionEvent evt) {
        if (tetris.getTitle().equals("Tetris-Multi")) {
            tetris.main.sendpausegame();
        } else {
            if (isStarted) {
                pauseButton.setText("Pause");
            } else if (isStarted && isPaused) {
                pauseButton.setText("Resume");
            }
            String str = pauseButton.getText();
            if (str.equals("Pause")) {
                pause();
            }
        }
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="exitButtonActionPerformed()">

    private void exitButtonActionPerformed(ActionEvent evt) {
        String str = tetris.getTitle();
        if (!isPaused) {
            pause();
        }
        int i = JOptionPane.showConfirmDialog(null, "do you want to quit now?");
        if (i == 0) {
            if (str.equals("Tetris")) {
                System.exit(-1);
            } else {
                tetris.dispose();
                Frame fr = new Frame(tetris.main);
                fr.setLocationRelativeTo(null);
                fr.loginPanel.removeAll();
                fr.setVisible(true);
                if (str.equals("Tetris-Single")) {
                    System.out.println(Integer.parseInt(scoreField.getText()));
                    //tetris.ghidiemlenserver(Integer.parseInt(scoreField.getText()));
                    fr.initChoosetypePanel();
                    tetris.dispose();
                } else if (str.equals("Tetris-Multi")) {
                    if (isStarted && tetris.numberOfUserLose < tetris.userListIndex - 1) {
                        tetris.main.sendgameover();
                    }
                    tetris.main.sendthoatkhoiphong();
                    fr.initChooseRoomPanel();
                }
            }
        }
    }// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="loginButtonActionPerformed()">

    private void loginButtonActionPerformed(ActionEvent evt) {
        //sever server = new sever();
        String str = loginButton.getText();
        System.out.println(str);
        String str1 = tetris.getTitle();
        if (str1.equals("Tetris")) {
            tetris.dispose();
            Main main = new Main();
        } else {
            if (str1.equals("Tetris-Multi")) {
                //System.out.println(str1);
                //tetris.main.sendthoatkhoiphong();
                //tetris.logout();
            } else {
                tetris.logout();


            }

        }

    }
// </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="class TAdapter()">
    class TAdapter extends KeyAdapter {

        public void keyPressed(KeyEvent e) {

            if (!isStarted || curPiece.getShape() == Shape.Tetrominoes.NoShape) {
                return;
            }

            int keycode = e.getKeyCode();

            if (keycode == 'p' || keycode == 'P') {
                pause();
                return;
            }

            if (isPaused) {
                return;
            }

            switch (keycode) {
                case KeyEvent.VK_A:
                    curX = 0;
                    break;

                case KeyEvent.VK_LEFT:
                    tryMove(curPiece, curX - 1, curY);
                    break;
                case KeyEvent.VK_RIGHT:
                    tryMove(curPiece, curX + 1, curY);
                    break;
                case KeyEvent.VK_DOWN:
                    //tryMove(curPiece.rotateRight(), curX, curY);
                    oneLineDown();
                    oneLineDown();
                    break;
                case KeyEvent.VK_UP:
                    tryMove(curPiece.rotateLeft(), curX, curY);
                    break;
                case KeyEvent.VK_SPACE:
                    dropDown();

                    break;
            }

        }
    }
// </editor-fold>
}